package com.gitee.andy.zpush.kernel;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadLocalRandom;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SessionContext {
	private static final Logger log = LoggerFactory.getLogger(SessionContext.class);
	private enum SelectorStrategyType {
		ALL, RANDOMONE
	}
	private final SelectorStrategyType selectorStrategyType;
	private ConcurrentHashMap<Integer, Session> sessions = new ConcurrentHashMap<>();
	private ExecutorService executor;

	private SessionContext(SelectorStrategyType selectorStrategyType, ExecutorService executor) {
		super();
		this.selectorStrategyType = selectorStrategyType;
		this.executor = executor;
	}

	public static SessionContext create(ExecutorService executor) {
		return new SessionContext(SelectorStrategyType.ALL, executor);
	}

	public static SessionContext createRand(ExecutorService executor) {
		return new SessionContext(SelectorStrategyType.RANDOMONE, executor);
	}

	public void add(Session session) {
		sessions.put(session.id(), session);
	}

	public void remove(Session session) {
		if (session != null) {
			sessions.remove(session.id());
		}
	}

	public void write(Object msg) {
		executor.execute(() -> {
			try {
				if (selectorStrategyType == SelectorStrategyType.ALL) {
					sessions.forEach((key, val) -> {
						val.write(msg);
					});
					log.info("wrtite to all msg..");
				} else if (selectorStrategyType == SelectorStrategyType.RANDOMONE) {
					ArrayList<Session> tmpSessionList = new ArrayList<>(sessions.values());
					if (!tmpSessionList.isEmpty()) {
						tmpSessionList.get(ThreadLocalRandom.current().nextInt(tmpSessionList.size())).write(msg);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
	}

	public void shutdown() {
		executor.shutdown();
	}
}
